/**
 * Universidad del Valle de Guatemala
 * Programacion Orientada a Objetos
 * Archivo: UsoCarteraVirtual.java
 * Proyecto 02: Cartera Virtual
 */

package CodigoFuente;
//Se importan los paquetes que nosotros creamos para la cartera virutal!
import InterfazGrafica.*;
import BaseDatos.*;
import Encriptacion.*;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.sql.*;
import java.util.*;

/**
 * @author Grupo 09
 * Descripcion: Clase principal de nuestro programa.
 */
public class UsoCarteraVirtual {

    private static GUICarteraVirtual CarteraVirtual = new GUICarteraVirtual();
    
    // Variables para la interaccion con la base de datos.
    private static String user = "root";
    private static String password = "";
    private static String dataBase = "carteravirtualsimple";
    private static String host = "localhost";
    private static String sSQL = null;
    private static PersistenciaSQL mysql = new PersistenciaSQL(host, user, password,
            dataBase);
    private static String contrasenaMaestra;
    
    //variables de los campos en los formularios de ingreso.
    private static String message = ""; //variable que mostrara el estado, u otra informacion
    
    //Instanciando el encriptador
    private static Encrypter encrypter = new Encrypter();

    //Creando el modelo de tabla.
    private static DefaultTableModel DTM_Tabla;


    /**
     * Metodo que verifica si ya existe almenos un usuario en la base de datos.
     * @return
     */
    public static boolean hayUsuario(){
        mysql.connect();
        boolean toReturn = false;
        String stSQL = "SELECT U_ID, U_Nombre1, U_Nombre2, U_Apellido1, U_Apellido2, U_Usuario, U_Contrasena FROM usuarios WHERE CONCAT(U_ID, ' ', U_Usuario) like '% %'";
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);
            ResultSet rs = pStatement.executeQuery(stSQL);
            if(rs.next()){
                toReturn = true;
            }
            else {
                toReturn = false;
            }
        }catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
        return toReturn;
    }

    /**
     * Metodo que se utiliza para verificar si el usuario y contraseña ingresados son válidos
     * @param usuarioX : el valor de usuario que se comparará con el de la base de datos
     * @param contrasenaX : el valor de la contrasena que se comparara con la de la base de datos
     * @return
     */
    public static boolean verificarUsuario(String usuarioX, String contrasenaX){
        mysql.connect();
        boolean toReturn = false;
        String stSQL = "SELECT U_Usuario, U_Contrasena FROM usuarios "
                + "WHERE CONCAT(U_Usuario, ' ', U_Contrasena) like '% %'";
        String usuario = "", contrasena = "";
        try {
           PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);
           ResultSet rs = pStatement.executeQuery(stSQL);
           while(rs.next()){
               usuario = encrypter.desencriptar(rs.getString("U_Usuario"));
               contrasena = encrypter.desencriptar(rs.getString("U_Contrasena"));
               if ((usuario.compareTo(usuarioX) == 0) && (contrasena.compareTo(contrasenaX) == 0)){
               toReturn = true;
               break;
               }
               else {
               toReturn = false;
               }
           }
        }catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
        return toReturn;
    }

    

    public static void vaciarBaseDatos(){
        mysql.connect();
        String sSQL1, sSQL2, sSQL3, sSQL4;
        sSQL1 = "TRUNCATE aplicaciones_internet";
        sSQL2 = "TRUNCATE dispositivos_electronicos";
        sSQL3 = "TRUNCATE membresias";
        sSQL4 = "TRUNCATE licencias_productos";
        
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(sSQL1);
            pStatement.executeQuery();
        }
        catch(Exception ex){
            JOptionPane.showMessageDialog(null, ex);
        }
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(sSQL2);
            pStatement.executeQuery();
        }
        catch(Exception ex){
            JOptionPane.showMessageDialog(null, ex);
        }
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(sSQL3);
            pStatement.executeQuery();
        }
        catch(Exception ex){
            JOptionPane.showMessageDialog(null, ex);
        }
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(sSQL4);
            pStatement.executeQuery();
        }
        catch(Exception ex){
            JOptionPane.showMessageDialog(null,ex);
        }
    }
    
    

    
    /**
     * Metodo utilizado para el cambio en contrasenas.
     * @param contrasenaActualX : la contrasena que se usara para verificarla.
     * @param contrasenaNuevaX : contrasena nueva por la que se cambiara.
     */
    public static void cambioDeContrasena(String usuarioX, ArrayList<String> tFields){
        mysql.connect();
        String usuario;
        String contrasena;
        String ID = "";
        boolean toReturn = false;
        String sSQL1 = "SELECT U_Usuario, U_Contrasena, U_ID FROM usuarios "
                + "WHERE CONCAT(U_Usuario, ' ', U_Contrasena) like '% %'";
        try{
            PreparedStatement pStatement = mysql.connection.prepareStatement(sSQL1);
           ResultSet rs = pStatement.executeQuery(sSQL1);
           while(rs.next()){
               
               usuario = encrypter.desencriptar(rs.getString("U_Usuario"));
               
               if ((usuario.compareTo(usuarioX) == 0)){
                   ID = rs.getString("U_ID");
               }
           }
        }
        catch(Exception ex){
            JOptionPane.showMessageDialog(null,ex);
        }
        String sSQL2 = "UPDATE usuarios "
                + "SET U_Contrasena = ? "
                + "WHERE U_ID = " + ID;
        message = "Cambio de Contraseña exitoso";
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(sSQL2);
                pStatement.setString(1,encrypter.encriptar(tFields.get(0)));      
                int cantElementos = pStatement.executeUpdate();
            if (cantElementos > 0) {
                JOptionPane.showMessageDialog(null, message);
            }
        }catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
    }
    
    
    /**
     * Metodo que realiza la busqueda en la base de datos.
     * @param filtroX : la palabra que se comparara para obtener los resultados
     * @param stSQL : la sentencia SQL que se ejecutará
     * @param titulosX : los titulos de los campos de una tabla.
     * @param registroX : el arrreglo en el que se guardaran temporalmente los datos.
     */
    public static void busquedaTablasSQL(String filtroX, String stSQL, String[] titulosX,
            String[] registroX) {
        mysql.connect();
        ArrayList<String> misDatosLineas = new ArrayList<String>();
        ArrayList<ArrayList<String>> misDatos = new ArrayList<ArrayList<String>>();
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);  
            ResultSet rs = pStatement.executeQuery(stSQL);            
            while(rs.next()){
                misDatosLineas.add(rs.getString(titulosX[0]));
                for(int x=1; x < titulosX.length; x++) {
                    misDatosLineas.add(encrypter.desencriptar(rs.getString(titulosX[x])));                    
                }
                misDatos.add(new ArrayList<String>(misDatosLineas));
                while (!misDatosLineas.isEmpty()){
                    misDatosLineas.remove(0);                
                }
            }
            for(int x=0; x< misDatos.size();x++){
                for(int y=0; y< misDatos.get(x).size();y++){
                    if(misDatos.get(x).get(y).compareTo(filtroX) == 0){
                        for(int z=0; z < misDatos.get(x).size(); z++){
                            registroX[z] = misDatos.get(x).get(z);                        
                        }
                    }
                }
                DTM_Tabla.addRow(registroX);
            }            
            CarteraVirtual.jT_BusquedaTablas.setModel(DTM_Tabla);            
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
    }
    
    /**
     * Metodo tulizado para cargar las tablas con todos su datos
     * @param stSQL : la sentencia SQL que se ejecutara
     * @param titulosX : los titulos de las columnas de la tabla
     * @param registroX : el arreglo en el que se guardaran temporalmente los datos de una fila
     */
    public static void cargarTablasSQL(String stSQL, String[] titulosX,
            String[] registroX){
        mysql.connect();
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);  
            ResultSet rs = pStatement.executeQuery(stSQL);            
            while(rs.next()){
                registroX[0] = rs.getString(titulosX[0]);
                for(int x=1; x < titulosX.length;x++){
                    registroX[x] = encrypter.desencriptar(rs.getString(titulosX[x]));
                }                   
                DTM_Tabla.addRow(registroX);
            }
            CarteraVirtual.jT_BusquedaTablas.setModel(DTM_Tabla);            
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }        
    }
    

    /**
     * Metodo que se utilizara para cargar la tabla de dispositivos electronicos.
     * @param filtroX : la palabra que se utilizara para la busquda.
     */
    public static void cargarTablaDispositivosElectronicos(String filtroX){
        String[] titulos = {"ID","Titulo","Usuario","Contrasena", "Extra1", "Extra2"};
        String[] titulosBD = {"DE_ID","DE_Titulo","DE_Usuario","DE_Contrasena", "DE_CampoExtra1" , "DE_CampoExtra2"};
        String[] registro = new String[6];
        DTM_Tabla = new DefaultTableModel(null, titulos);
        sSQL = "SELECT DE_ID, DE_Titulo, DE_Usuario, DE_Contrasena, DE_CampoExtra1, DE_CampoExtra2 FROM dispositivos_electronicos "
                + "WHERE CONCAT(DE_ID, ' ', DE_Titulo,' ',DE_Usuario) like '% %'";
        if(filtroX.equals("")){
            cargarTablasSQL(sSQL, titulosBD, registro);
        }
        else if(!filtroX.equals("")){
            busquedaTablasSQL(filtroX, sSQL, titulosBD, registro);
        }       
    }
    
    /**
     * Metodo que se utilizara para cargar la tabla de Membresias.
     * @param filtroX : la palabra que se utilizara para la busquda.
     */
    public static void cargarTablaMembresias(String filtroX){
        String[] titulos = {"ID", "Titulo", "Usuario", "Contrasena", "F. Adquisicion", "F. Expiracion", "Extra1", "Extra2"};
        String[] titulosBD = {"M_ID", "M_Titulo", "M_Usuario", "M_Contrasena", "M_FechaAdquisicion", "M_FechaExpiracion", "M_CampoExtra1", "M_CampoExtra2"};
        String[] registro = new String[8];
        DTM_Tabla = new DefaultTableModel(null, titulos);
        sSQL = "SELECT M_ID, M_Titulo, M_Usuario, M_Contrasena, M_FechaAdquisicion, M_FechaExpiracion, M_CampoExtra1, M_CampoExtra2 FROM membresias "
                + "WHERE CONCAT(M_Titulo, ' ', M_Usuario) LIKE '% %'";
        if(filtroX.equals("")){
            cargarTablasSQL(sSQL, titulosBD, registro);
        }
        else if(!filtroX.equals("")){
            busquedaTablasSQL(filtroX, sSQL, titulosBD, registro);
        }
    }
    
    /**
     * Metodo que se utilizara para cargar la tabla de aplicaciones de internet.
     * @param filtroX : la palabra que se utilizara para la busquda.
     */
    public static void cargarTablaAplicacionesInternet(String filtroX){
        String[] titulos = {"ID", "Titulo", "Link", "Usuario", "Contrasena","Extra1", "Extra2"};
        String[] titulosBD = {"AI_ID", "AI_Titulo", "AI_Link", "AI_Usuario", "AI_Contrasena", "AI_CampoExtra1", "AI_CampoExtra2"};
        String[] registro = new String[7];
        DTM_Tabla = new DefaultTableModel(null, titulos);
        sSQL = "SELECT AI_ID, AI_Titulo, AI_Link, AI_Usuario, AI_Contrasena, AI_CampoExtra1, AI_CampoExtra2 FROM aplicaciones_internet "
                + "WHERE CONCAT(AI_Titulo, ' ', AI_Usuario, ' ', AI_Link) LIKE '% %'";
        if(filtroX.equals("")){
            cargarTablasSQL(sSQL, titulosBD, registro);
        }
        else if(!filtroX.equals("")){
            busquedaTablasSQL(filtroX, sSQL, titulosBD, registro);
        }
    }
    
    /**
     * Metodo que se utilizara para cargar la tabla de licencias de Productos.
     * @param filtroX : la palabra que se utilizara para la busquda.
     */
    public static void cargarTablaLicenciasProductos(String filtroX){
        String[] titulos = {"ID", "Titulo", "Usuario", "Contrasena", "Link", "No. Serie", "Key", "F. Adquisicion", "F. Expiracion", "Extra1", "Extra2"};
        String[] titulosBD = {"LP_ID", "LP_Titulo", "LP_Usuario", "LP_Contrasena", "LP_Link", "LP_NoSerie", "LP_Key", "LP_FechaAdquisicion", "LP_FechaExpiracion", "LP_CampoExtra1", "LP_CampoExtra2"};
        String[] registro = new String[11];
        DTM_Tabla = new DefaultTableModel(null, titulos);
        sSQL = "SELECT LP_ID, LP_Titulo, LP_Usuario, LP_Contrasena, LP_Link, LP_NoSerie, LP_Key, LP_FechaAdquisicion, LP_FechaExpiracion, LP_CampoExtra1, LP_CampoExtra2 FROM licencias_productos "
                + "WHERE CONCAT(LP_Titulo, ' ', LP_Usuario, ' ', LP_Link) LIKE '% %'";
        if(filtroX.equals("")){
            cargarTablasSQL(sSQL, titulosBD, registro);
        }
        else if(!filtroX.equals("")){
            busquedaTablasSQL(filtroX, sSQL, titulosBD, registro);
        }
    }
    
    
    /**
     * Metodo quer realiza el proceso de conección con la base de datos y guardad0
     * de los datos
     * @param stSQL : Statemente SQL, es la instrucción que se desea realizar.
     * @param tFields : los datos con los que resalizará la instrucción.
     */
    public static void guardarEnBaseDatos(String stSQL, ArrayList<String> tFields){
        mysql.connect();
        message = "Los datos se han insertado de forma exitosa";
        try {
            PreparedStatement pStatement = mysql.connection.prepareStatement(stSQL);
            for(int x=0; x < tFields.size(); x++){
                pStatement.setString((x+1),encrypter.encriptar(tFields.get(x)));
            }
            int cantElementos = pStatement.executeUpdate();
            if (cantElementos > 0) {
                JOptionPane.showMessageDialog(null, message);
            }
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
       }
    }
    public static String camposDE = "";
    public static int valuesDE = 3;

    /**
     * Metodo utilizado para agregar un dispositivo Electronico.
     * @param tFields : Arreglo de datos del dispositivo electronico que se desea
     * agregar.
     */
    public static void agregarDispositivoElectronico(ArrayList<String> tFields) {
        sSQL = "INSERT INTO dispositivos_electronicos(DE_Titulo, DE_Usuario, "
                + "DE_Contrasena, DE_CampoExtra1, DE_CampoExtra2) VALUES(?,?,?,?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }

    /**
     * Metodo utilizado para agregar un usuario.
     * @param tFields : Arreglo de datos del nuevo usuario que se desea
     * agregar.
     */
    public static void agregarUsuario(ArrayList<String> tFields) {
        sSQL = "INSERT INTO usuarios(U_Nombre1, U_Nombre2, U_Apellido1, " +
                "U_Apellido2, U_Usuario, U_Contrasena) VALUES(?,?,?,?,?,?)";
        guardarEnBaseDatos(sSQL,tFields);
    }
    

    /**
     * Metodo utilizado para agregar una membresia.
     * @param tFields : Arregki de datos de la membresia que se desea agregar.
     */
    public static void agregarMembresia(ArrayList<String> tFields) {
        sSQL = "INSERT INTO membresias(M_Titulo, M_Usuario, M_Contrasena, "
                + "M_FechaAdquisicion, M_FechaExpiracion, M_CampoExtra1, M_CampoExtra2)"
                + " VALUES(?, ?, ?, ?, ?, ?, ?)";
        guardarEnBaseDatos(sSQL, tFields);
    }

    /**
     * Metodo para agregar nuevas aplicaciones de Internet.
     * @param tFields : Arreglo con los datos de la aplicacion de internet que se agregará
     */
    public static void agregarAplicacionesInternet(ArrayList<String> tFields) {
        sSQL = "INSERT INTO aplicaciones_internet(AI_Titulo, AI_Link, AI_Usuario, "
                + "AI_Contrasena, AI_CampoExtra1, AI_CampoExtra2) VALUES(?, ?, ?, ?, ?, ?)";
        guardarEnBaseDatos(sSQL, tFields);
    }
    
    /**
     * Metodo para agregar una nueva licencia de productos
     * @param tFields : Arreglo de datos de la nueva licencia que se agregará 
     */
    public static void agregarLicenciaProductos(ArrayList<String> tFields) {
        sSQL = "INSERT INTO licencias_productos(LP_Titulo, LP_Usuario, LP_Contrasena, LP_Link,"
                + "LP_NoSerie, LP_Key, LP_FechaAdquisicion, LP_FechaExpiracion, LP_CampoExtra1, "
                + "LP_CampoExtra2)"
                + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        guardarEnBaseDatos(sSQL, tFields);
    }

    /**
     * Metodo utilizado para generar una contraseña de numeros aleatorios!
     * @return 
     */
    public static String generarContrasena(){
        String contrasenaSugerida="";
        Random generator = new Random(); 
        int num;
        num = generator.nextInt(26) + 65;
        char a = (char)num;
        num = generator.nextInt(26) + 65;
        char b = (char)num;
        num = generator.nextInt(26) + 65;
        char c = (char)num;
        num = generator.nextInt(26) + 65;
        char d = (char)num;
        String s = new StringBuilder().append(b).append(c).append(d).append(a).toString();
        String cadena=""; 
        for (int i=0;i<2;i++){
            num = generator.nextInt(100);
            cadena=cadena+Integer.toString(num);
        }
        contrasenaSugerida=s+cadena;     
        return contrasenaSugerida;
    }
    
    /**
     * Metodo principal del programa, instancia la interfáz grafica.
     * @param args 
     */
    public static void main(String args[]) {
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GUICarteraVirtual.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GUICarteraVirtual.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GUICarteraVirtual.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GUICarteraVirtual.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                CarteraVirtual.setVisible(true);
            }
        });
    }
}
